Etter å ha lest Hidden Features and Dark Corners of C ++ / STL på comp.lang.c ++. Moderert, ble jeg helt overrasket over at følgende kodebit samlet og jobbet i både Visual Studio 2008 og G ++ 4.4. Her er koden: # inkludererint main () { int x = 10; mens (x -> 0) // x går til 0 { printf ("% d", x); } } Produksjon: 9 8 7 6 5 4 3 2 1 0 Jeg antar at dette er C, siden det også fungerer i GCC. Hvor er dette definert i standarden, og hvor har den kommet fra?
2020-12-07 21:24:47
-> er ikke operatør. Det er faktisk to separate operatører, - og>. Betingelsens kode reduseres x mens den returnerer xs opprinnelige (ikke reduserte) verdi, og sammenligner deretter den opprinnelige verdien med 0 ved hjelp av> operatoren. For bedre å forstå kan uttalelsen skrives som følger: mens ((x--)> 0) | Eller for noe helt annet ... x glir til 0. mens (x - \ \ \ \ > 0) printf ("% d", x); Ikke så matematisk, men ... hvert bilde maler tusen ord ... | Det er en veldig komplisert operatør, så selv ISO / IEC JTC1 (Joint Technical Committee 1) plasserte beskrivelsen i to forskjellige deler av C ++ Standard. Spøk til side, de er to forskjellige operatører: - og> beskrevet henholdsvis i §5.2.6 / 2 og §5.9 i C ++ 03-standarden. | Det tilsvarer mens (x--> 0) x-- (post decrement) tilsvarer x = x-1, så koden forvandles til: mens (x> 0) { x = x-1; // logikk } x--; // Innleggsreduksjonen gjort når x <= 0 | x kan gå til null enda raskere i motsatt retning: int x = 10; mens (0 <---- x) { printf ("% d", x); } 8 6 4 2 Du kan kontrollere hastigheten med en pil! int x = 100; mens (0 <-------------------- x) { printf ("% d", x); } 90 80 70 60 50 40 30 20 10 ;) | Det er # inkludererint main (ugyldig) { int x = 10; mens (x--> 0) {// x går til 0 printf ("% d", x); } retur 0; } Bare plassen får ting til å se morsomme ut, - nedgang og> sammenligner. | Bruk av -> har historisk relevans. Dekrementering var (og er fortsatt i noen tilfeller), raskere enn å øke på x86-arkitekturen. Å bruke -> antyder at x går til 0, og appellerer til de med matematisk bakgrunn. | mens (x--> 0) er hvordan det blir analysert. | Helt nerd, men jeg vil bruke dette: #definer som; mens int main (int argc, char * argv []) { int n = atoi (argv [1]); gjør printf ("n er% d \ n", n) som (n -> 0); retur 0; } | En bok jeg leste (jeg husker ikke riktig hvilken bok) uttalte: Kompilatorer prøver å analysere uttrykk til det største symbolet ved å bruke regelen til venstre for høyre. I dette tilfellet uttrykket: x -> 0 Deler til største tokens: token 1: x token 2: - token 3:> token 4: 0 konkluder: x--> 0 Den samme regelen gjelder for dette uttrykket: a ----- b Etter analyse: token 1: a token 2: - token 3: - token 4: - token 5: b konkludere: (a -) - - b Jeg håper dette hjelper til å forstå det kompliserte uttrykket ^^ | Dette er nøyaktig det samme som mens (x--) { printf ("% d", x); } for ikke-negative tall | Uansett, vi har en "går til" -operatør nå. "->" er lett å bli husket som en retning, og "mens x går til null" betyr-rett. Videre er det litt mer effektivt enn "for (x = 10; x> 0; x -)" på noen plattformer. | Denne koden sammenligner først x og 0 og reduseres deretter x. (Også sagt i det første svaret: Du etterdekrimerer x og sammenligner deretter x og 0 med> operatøren.) Se utdataene til denne koden: 9 8 7 6 5 4 3 2 1 0 Vi sammenligner nå først og deretter reduseres ved å se 0 i utdataene. Hvis vi først vil redusere og deretter sammenligne, bruk denne koden: # inkluderer int main (ugyldig) { int x = 10; mens (--x> 0) // x går til 0 { printf ("% d", x); } retur 0; } Den produksjonen er: 9 8 7 6 5 4 3 2 1 | Kompilatoren min skriver ut 9876543210 når jeg kjører denne koden. # inkluderer int main () { int x = 10; mens (x -> 0) // x går til 0 { std :: cout << x; } } Som forventet. Mens (x--> 0) betyr faktisk mens (x> 0). Nedgangen på x-- innlegg x. mens (x> 0) { x--; std :: cout << x; } er en annen måte å skrive det samme på. Det er hyggelig at originalen ser ut som "mens x går til 0" skjønt. | Det mangler et mellomrom mellom - og>. x er post dekrementert, det vil si dekrementert etter å ha sjekket tilstanden x> 0?. | - er reduksjonsoperatøren og> er operatøren som er større enn. De to operatørene brukes som en som ->. | Det er en kombinasjon av to operatører. Først - er for å redusere verdien, og> er for å sjekke om verdien er større enn høyre operand. # inkluderer int main () { int x = 10; mens (x--> 0) printf ("% d", x); retur 0; } Resultatet blir: 9 8 7 6 5 4 3 2 1 0 | Egentlig er x etter dekrementering og med den tilstanden blir det sjekket. Det er ikke ->, det er (x--)> 0 Merk: verdien av x endres etter at tilstanden er sjekket, fordi den etter dekrementering. Noen lignende tilfeller kan også forekomme, for eksempel: -> x -> 0 ++> x ++> 0 -> = x -> = 0 ++> = x ++> = 0 | C og C ++ følger "maksimal munch" -regelen. På samme måte som a --- b oversettes til (a--) - b, i ditt tilfelle x -> 0 oversettes til (x -)> 0. Det som regelen i det vesentlige sier, er at uttrykk fra venstre til høyre dannes ved å ta maksimalt antall tegn som vil danne et gyldig uttrykk. | Hvorfor hele komplikasjonen? Det enkle svaret på det opprinnelige spørsmålet er bare: # inkluderer int main () { int x = 10; mens (x>0) { printf ("% d", x); x = x-1; } } Det gjør det samme. Jeg sier ikke at du skal gjøre det slik, men det gjør det samme og ville ha svart på spørsmålet i ett innlegg. X-- er bare stenografi for ovennevnte, og> er bare en normal større enn operatør. Ikke noe stort mysterium! Det er for mange mennesker som gjør enkle ting kompliserte i dag;) | På den konvensjonelle måten vil vi definere en tilstand i mens løkke parentes () og en avslutningstilstand inne i selene {}, men -> definerer begge på en gang. For eksempel: int abc (ugyldig) { int a = 5 mens ((a--)> 0) // Reduksjon og sammenligning begge på en gang { // Kode } } Dette reduserer a og kjører løkken mens a er større enn 0. Konvensjonelt vil det være som: int abc (ugyldig) { int a = 5; mens (a> 0) { en--; // Kode } en--; } Begge veiene gjør vi det samme og oppnår de samme målene. | (x -> 0) betyr (x--> 0). Du kan bruke (x ->) Utgang: 9 8 7 6 5 4 3 2 1 0 Du kan bruke (- x> 0) Det er gjennomsnittlig (--x> 0) Output: 9 8 7 6 5 4 3 2 1 Du kan bruke (- \ \ x> 0) Utgang: 9 8 7 6 5 4 3 2 1 Du kan bruke (\ \ x -> 0) Utgang: 9 8 7 6 5 4 3 2 1 0 Du kan bruke (\ \ x -> 0 \ \ ) Utgang: 9 8 7 6 5 4 3 2 1 0 Du kan også bruke ( x -> ) Utgang: 9 8 7 6 5 4 3 2 1 0 På samme måte kan du prøve mange metoder for å utføre denne kommandoen vellykket. | Her - er den unære operatøren for avkorting. mens (x--> 0) // x går til 0 { printf ("% d", x); } I begynnelsen vil tilstanden evaluere som (x> 0) // 10> 0 Nå som tilstanden er sann, vil den gå inn i løkken med en redusert verdi x-- // x = 9 Derfor er den første trykte verdien 9 Og så videre. I den siste sløyfen x = 1, så tilstanden er sant. I henhold til den unare operatøren endret verdien til x = 0 på utskriftstidspunktet. Nå er x = 0, som evaluerer tilstanden (x> 0) som falsk og mens løkken går ut. | Dette -> er ikke en operatør i det hele tatt. Vi har en operatør som ->, men ikke som ->. Det er bare en feil tolkning av mens (x--> 0), som ganske enkelt betyr at x har post-decrement-operatøren, og denne sløyfen vil kjøre til den er større enn null. En annen enkel måte å skrive denne koden på ville være mens (x--). Mens sløyfen stopper når den får en falsk tilstand, og her er det bare ett tilfelle, dvs. 0. Så den vil stoppe når x-verdien blir redusert til null. | Svært aktivt spørsmål. Tjen 10 rykte for å svare på dette spørsmålet. Omdømmekravet hjelper deg med å beskytte dette spørsmålet mot spam og ikke-svar-aktivitet. Er ikke svaret du leter etter? Bla gjennom andre spørsmål som er merket med c ++ c-operatører, kodeformatering, standarder, eller still dine egne spørsmål.